using Dapper;
using DapperExtensions;
using SmartLink.Domain.Entity;
using SmartLink.EnumLibrary;
using SmartLink.IRepository;
using SmartLink.Repository.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SmartLink.Repository
{
    public class SYS_ModuleFunctionRepo : RepositoryBase<SYS_ModuleFunction>, ISYS_ModuleFunctionRepo
    {
        public bool Exist(string moduleCode, string code)
        {
            var predicate = new PredicateGroup
            {
                Operator = GroupOperator.And,
                Predicates = new List<IPredicate>
                    {
                        Predicates.Field<SYS_ModuleFunction>(f => f.ModuleCode, Operator.Eq, moduleCode),
                        Predicates.Field<SYS_ModuleFunction>(f => f.Code, Operator.Eq, code.Trim()),
                        Predicates.Field<SYS_ModuleFunction>(f => f.IsDel, Operator.Eq, false)
                    }
            };
            using (var conn = CreateConn())
            {
                IDatabase db = GetIDataBase(conn);
                var list = db.Count<SYS_ModuleFunction>(predicate);
                return list > 0;
            }
        }

        public bool Repeat(int id, string moduleCode, string newCode)
        {
            var predicate = new PredicateGroup
            {
                Operator = GroupOperator.And,
                Predicates = new List<IPredicate>
                    {
                        Predicates.Field<SYS_ModuleFunction>(f => f.ModuleCode, Operator.Eq, moduleCode),
                        Predicates.Field<SYS_ModuleFunction>(f => f.ID, Operator.Eq, id, true),
                        Predicates.Field<SYS_ModuleFunction>(f => f.Code, Operator.Eq, newCode.Trim()),
                        Predicates.Field<SYS_ModuleFunction>(f => f.IsDel, Operator.Eq, false)
                    }
            };
            using (var conn = CreateConn())
            {
                IDatabase db = GetIDataBase(conn);
                var list = db.Count<SYS_ModuleFunction>(predicate);
                return list > 0;
            }
        }

        public IEnumerable<SYS_ModuleFunction> GetList(string moduleCode)
        {
            var predicate = new PredicateGroup
            {
                Operator = GroupOperator.And,
                Predicates = new List<IPredicate>
                    {
                        Predicates.Field<SYS_ModuleFunction>(f => f.ModuleCode, Operator.Eq, moduleCode),
                        Predicates.Field<SYS_ModuleFunction>(f => f.IsDel, Operator.Eq, false)
                    }
            };
            IList<ISort> sort = new List<ISort> { Predicates.Sort<SYS_ModuleFunction>(p => p.Sort) };
            using (var conn = CreateConn())
            {
                IDatabase db = GetIDataBase(conn);
                var list = db.GetList<SYS_ModuleFunction>(predicate, sort);
                return list;
            }
        }

        public IEnumerable<SYS_ModuleFunction> GetAuthorizedFunctions(AuthorizationOwnerTypeEnum ownerType, params int[] ownerIds)
        {
            var sql = $@"SELECT mf.* FROM SYS_ModuleFunction mf
                                  JOIN PER_ActionAuthorization aa ON aa.ItemType={(int)AuthorizationItemTypeEnum.Function} AND aa.ItemID=mf.ID
                                  WHERE aa.OwnerType={(int)ownerType} AND aa.OwnerID IN ({string.Join(",", ownerIds)})";
            using (var conn = CreateConn())
            {
                return conn.Query<SYS_ModuleFunction>(sql);
            }
        }

        public IEnumerable<SYS_ModuleFunction> GetOrgManagerModuleFunctions()
        {
            var sql = $@"SELECT mf.* 
                           FROM SYS_ModuleFunction mf
                     INNER JOIN SYS_Module m ON m.Code=mf.ModuleCode AND m.IsDel=0
                          WHERE NOT FIND_IN_SET(m.Code, @ModuleConcatStr)
                            AND mf.IsDel=0";
            var superAdminOnlyModuleConcatStr = string.Join(",", SuperAdminOnlyModule.Modules);
            using (var conn = CreateConn())
            {
                return conn.Query<SYS_ModuleFunction>(sql, new { ModuleConcatStr = superAdminOnlyModuleConcatStr });
            }
        }
    }
}
